﻿using Newtonsoft.Json;
using SoldiHive.Core;
using SoldiHive.Core.Adapters;
using SoldiHive.Core.Cache;
using SoldiHive.Core.Crawlers;
using SoldiHive.Core.NodeJs;
using SoldiHive.Core.Persistence;
using System;
using System.Collections.Generic;
using System.IO;

namespace SoldiHive.Configuration
{
	public class ConfigurationFactory
	{
		private static string configurationFile = "Configuration.json";

		private static Configuration configurationRoot;
		private static IDictionary<Type, Func<Configuration, object>> selectorsMap;

		static ConfigurationFactory()
		{
			ConfigurationFactory.selectorsMap = new Dictionary<Type, Func<Configuration, object>>()
			{
				{ typeof(IAdapterConfiguration), s => s.Adapter },
				{ typeof(ICacheConfiguration), s => s.Cache },
				{ typeof(IScriptExecutorConfiguration), s => s.ScriptExecutor },
				{ typeof(ICompanyRepositoryConfiguration), s => s.CompanyRepositroy },
				{ typeof(IQuoteRepositoryConfiguration), s => s.QuoteRepositroy },
				{ typeof(IRatingStrategyConfiguration), s => s.RatingStrategy },
				{ typeof(IMarketViewerConfiguration), s => s.MarketViewer },
				{ typeof(IRatingsCrawlerConfiguration), s => s.RatingsCrawler }
			};

			using (var jsonConfigurationFileStream = File.OpenRead(ConfigurationFactory.configurationFile))
			using (var jsonConfigurationFileReader = new StreamReader(jsonConfigurationFileStream))
			{
				var jsonConfiguration = jsonConfigurationFileReader.ReadToEnd();
				ConfigurationFactory.configurationRoot = JsonConvert.DeserializeObject<Configuration>(jsonConfiguration);
			}
		}

		public static TConfiguration GetConfiguration<TConfiguration>()
		{
			var type = typeof(TConfiguration);
			var configurationSelector = ConfigurationFactory.selectorsMap[type];

			var configuration = configurationSelector(ConfigurationFactory.configurationRoot);

			return (TConfiguration)configuration;
		}
	}
}
